全局变量，局部变量

1. 未经声明的变量直接赋值，归window所有，是全局变量,window是一个对象
a=10;
相当于window.a = 10; 
window{
    a : 10; a是window的属性
}

2.一切声明的全局变量，全是window的属性
var a = 123; ==>  window.a = 123;
window就是全局的域，a放到window里，相当于在window里var了一个a=123,window相当于一个仓库
console.log(a) 在全局的范围访问a的话，就是访问window.a,console.log(window.a)
window{
    a : 123;
}

<script>
    function test(){
        var a = b =1;
        console.log(b); /*全局变量,归window所有，window.b=1*/
    }
    console.log(a); /*局部变量，在全局打印为undefined*/
</script>
var a = b = 1; 先把1赋值给b，再var a 声明a,再把b值给a,b没有声明，未经声明就赋值 值归window所有

js运行三步
语法分析，预编译，解释执行
js是解释型语言，解释一行，执行一行，在执行之前会通篇扫描，检查语法错误

1.imply global 暗示全局变量:即任何变量，如果变量未经声明就赋值，此变量就为全局对象所有，eg: a = 123; var a = b =123;
2.一切声明的全局变量，全是window的属性

预编译
<script>
    console.log(a); //undefined,按理说应该报错，能输出Undefined就是预编译过程特殊的效果
    var a = 123;
</script>

//函数声明整体提升，如果写一个函数，不管写到哪里，都会把函数提到逻辑的最前面，不管在哪儿调用本质上都是在函数的下面调用
//变量  声明提升

1.创建AO对象 ,Activation Object活跃对象（执行期上下文）
2.找形参和变量声明，将变量名和形参名作为AO属性名，值为undifined
3.将实参值和形参值统一
4.在函数体里面找函数声明，值赋予函数体

<script>
    function fn(a){
        console.log(a);  //a:function a(){}
        var a = 123;    //var a 在预编译已经读过，不需要重读，变量声明提升，被提到最前面，不用再提，a = 123  a赋值123;
        console.log(a);  // 123
        function a(){}  //预编译读过
        console.log(a);  // 123
        var b = function (){} 
        console.log(b);
        function d(){}
    }
    fn(1);
    // 预编译发生在函数执行的前一刻
</script>

1.创建AO对象
AO{}
2.找形参和变量声明，将变量和形参名作为AO属性名，值为undifined
形参function fn(a)中的a ，变量声明var b = function (){}中的b
AO{
    a:undifined
    b:undefined
}
3.将实参值和形参值统一
fn(1)中的1给fn(a)中的a
AO{
    a:1
    b:undefined
}
4.在函数体里面找函数声明，值赋予函数体
AO{
    a:function a(){};
    b:undefined;
    d:function d(){}
}

<script>
    
    // GO{
    //     b : 123;
    // b在GO里
    // }
    function test(){
        var a = b = 123; /* b是暗示全局变量，没经声明就赋值，归window所有即全局GO所有 */
    }
//     执行test()时生成一个 AO{
//     a: undefined;
//     对b无动于衷，没声明，b不是参数，没函数声明
// }
    
    console.log(b); /*值为123*/
    console.log(a); /*报错*/
    
</script>


<script>
    console.log(test);
    function test(test){
        console.log(test); /*打印AO的test*/
        var test = 234;
        console.log(test); //234
        function test (){};
    }
    test(1);
    var test = 123;

//    创建go对象 GO{
//     test: function test (){
//         //...
//     }
// }


    // 1 创建AO对象 AO{
    //     2 test : undefined 形参和变量声明
    //     3 test : 1  形参实参统一test(1)
    //     4 test : function test(){} 函数体赋值

    // }
</script>

<script type="text/javascript">
    // GO{
    //    global 100
    //}

    var global = 100;
    function fn(){
        console.log(global)
    }
    // fn执行产生AO{
    //  
    //}
    fn()
</script>

<script>
    // GO{
    //    global = undefined; 预编译
    //    global = 100 执行时
    // }

    global = 100;
    function fn(){
        console.log(global); // undefined
        global = 200;
        console.log(global); //200
        var global = 300;
    }
    fn();
    // AO{
    //    global = undefined;
    //}
    var global;
</script>

<script>
    // GO{
    //  a : undefined
    //  c : 234  执行test()时
    //}

    function test(){
        console.log(b); // undefined
        if(a){          //a 为undefined ,不执行
            var b = 100; 
        }
        console.log(b); //undefined 
        c = 234;
        console.log(c)  //234
    }

    var a;
    test();
    // AO{
    //    b : undefined
    //}

    a = 10;
    console.log(c); // 234
</script>

<script>
    function bar(){
        return foo;
        foo = 10;
        function foo(){

        }
        var foo = 11;
    }
    console.log(bar()) // function foo(){}
    
</script>

<script>
    console.log(bar());  // 11
        foo = 11;
        function bar (){
            foo = 10;
            function foo(){

            }
            var foo = 11;
            return foo;
        }
</script>

<script type="text/javascript">
    a = 10;
    function demo e{
        function e(){};
        arguments[0] = 2;
        console.log(e)
        if(a){
            var b = 123;
            function c(){}
        }
        var c;
        a = 10;
        var a;
        console.log(b);
        f = 10;
        console.log(c);
        console.log(a);
    }
    var a;
    demo(1);
    console.log(a);
    console.log(f);
</script>

<script type="text/javascript">
    var str = false + 1;//false转化为数字类型为1
    document.write(str);
    var demo = false == 1;//false是否为1，不为1,值为false
    document.write(demo);

    //undefined && - 1 + (+ undefined) + '';
    //undefined && NaN + '';
    //undefined && 'NaN';
    //false && ture;
    if(typeof(a) && - true + (+ undefined) + ''){
        document.write('基础扎实')；
    }
    if(11 + '11' * 2 == 33){
        document.write('基础扎实')
    }
    !!" " + !!"" - !!false || document.write('不能打印')//true + false - false;
</script>